#include "logger.h"
#include <iostream>
#include <filesystem>

namespace x{
	Logger& Logger::getinstance(){
		static Logger instance;
		return instance;
	}

	Logger::~Logger(){
		shutdown();
	}
	bool Logger::init(const LoggerCfg& config=LoggerCfg{}){
		if(initialized_){
			std::cerr<<"警告：日志系统已初始化"<<std::endl;
			return true;
		}

		loggercfg_=config;

		try{
			std::vector<spdlog::sink_ptr> sinks;

			if(loggercfg_.enable_console){
				auto console_sink=std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
				console_sink->set_level(tospdloglevel(loggercfg_.level));
				console_sink->set_pattern(loggercfg_.pattern);
				sinks.push_back(console_sink);
			}

			if(loggercfg_.enable_file){
				if(!createlogdir(loggercfg_.log_path)){
					std::cerr<<"错误：无法创建日志文件"<<std::endl;
					return false;
				}

				auto file_sink=std::make_shared<spdlog::sinks::rotating_file_sink_mt>(
					loggercfg_.log_path,
					loggercfg_.max_file_size,
					loggercfg_.max_files
				);
				file_sink->set_level(tospdloglevel(loggercfg_.level));
				file_sink->set_pattern(loggercfg_.pattern);
				sinks.push_back(file_sink);
			}

			if(sinks.empty()){
				std::cerr<<"错误：至少需要一种日志输出方式"<<std::endl;
				return false;
			}

			logger_=std::make_shared<spdlog::logger>(loggercfg_.name,sinks.begin(),sinks.end());

			logger_->set_level(tospdloglevel(loggercfg_.level));

			if(loggercfg_.auto_flush){
				logger_->flush_on(spdlog::level::info);
			}

			spdlog::register_logger(logger_);

			spdlog::set_default_logger(logger_);

			initialized_=true;

			LOG_INFO("日志系统初始化成功 - 名称: {}, 级别: {}, 控制台: {}, 文件: {}", 
                loggercfg_.name, 
                static_cast<int>(loggercfg_.level),
                loggercfg_.enable_console ? "启用" : "禁用",
                loggercfg_.enable_file ? loggercfg_.log_path : "禁用");
			return true;
		}
		catch(const std::exception& e){
			std::cerr<<"错误：初始化日志系统失败："<<e.what()<<std::endl;
			return false;
		}
	}
	void Logger::setlevel(LogLevel level){
		if(!initialized_ || !logger_){
			std::cerr<<"警告：日志系统未初始化，无法设置日志级别"<<std::endl;
			return;
		}

		loggercfg_.level=level;
		logger_->set_level(tospdloglevel(level));

		for(auto& sink:logger_->sinks()){
			sink->set_level(tospdloglevel(level));
		}

		LOG_INFO("日志级别更新为：{}",static_cast<int>(level));
	}

	LogLevel Logger::getlevel() const{
		return loggercfg_.level;
	}

	void Logger::flush(){
		if(logger_){
			logger_->flush();
		}
	}

	void Logger::shutdown(){
		if(!initialized_){
			return;
		}

		try{
			if(logger_){
				LOG_INFO("日志系统正在关闭中...");
				logger_->flush();
				spdlog::drop(loggercfg_.name);
				logger_.reset();
			}

			spdlog::shutdown();

			initialized_=false;
		}
		catch (const std::exception& e) {
        	std::cerr << "警告: 关闭日志系统时发生错误: " << e.what() << std::endl;
    	}
	}

	spdlog::level::level_enum Logger::tospdloglevel(LogLevel level){
		switch (level)
		{
			case LogLevel::TRACE: return spdlog::level::trace;
			case LogLevel::DEBUG: return spdlog::level::debug;
			case LogLevel::INFO: return spdlog::level::info;
			case LogLevel::WARN: return spdlog::level::warn;
			case LogLevel::ERROR: return spdlog::level::err;
			case LogLevel::CRITICAL: return spdlog::level::critical;
			default: return spdlog::level::info;
		}
	}

	bool Logger::createlogdir(const std::string& log_path){
		try {
        	std::filesystem::path path(log_path);
        	std::filesystem::path dir = path.parent_path();
        
        	if (!dir.empty() && !std::filesystem::exists(dir)) {
            	std::filesystem::create_directories(dir);
        	}
        
        	return true;
        
    	} catch (const std::exception& e) {
        	std::cerr << "错误: 创建日志目录失败: " << e.what() << std::endl;
        	return false;
    	}
	}
}